package stack

import "fmt"

type ArrayStack struct {
	data     []interface{}
	top      int
	capacity int
}

func NewArrayStack(capacity int) *ArrayStack {
	return &ArrayStack{
		data:     make([]interface{}, 0, 32),
		top:      -1,
		capacity: capacity,
	}
}

func (this *ArrayStack) IsEmpty() bool {
	if this.top < 0 {
		return true
	}
	return false
}

func (this *ArrayStack) IsFull() bool {
	if this.top == this.capacity-1 {
		return true
	}
	return false
}

func (this *ArrayStack) Push(v interface{}) bool {
	if this.IsEmpty() {
		this.top = 0
	} else {
		if this.IsFull() {
			return false
		}
		this.top++
	}

	this.data[this.top] = v
	return true
}

func (this *ArrayStack) Pop() interface{} {
	if this.IsEmpty() {
		return nil
	}
	v := this.data[this.top]
	this.top--
	return v
}

func (this *ArrayStack) Top() interface{} {
	if this.IsEmpty() {
		return nil
	}
	return this.data[this.top]
}

func (this *ArrayStack) Flush() {
	this.top = -1
	this.data = make([]interface{}, this.capacity)
}

func (this *ArrayStack) Print() string {
	if this.IsEmpty() {
		return "empty stack"
	}
	result := "top->"
	for i := this.top; i >= 0; i-- {
		result += fmt.Sprintf("%+v->", this.data[i])
	}
	return result
}
